/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kuti.grp5;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import kuti.*;

/**
 * @author Marc Schorderet <marc.schorderet@edu.hefr.ch>
 * @author Vincenzo Do <vincenzo.do@edu.hefr.ch>
 * @version 1.0
 *
 * @see IFactory
 */
public class Factory implements IFactory {

    private ISimulParams simulParams;

    public Factory(ISimulParams isp) {
        simulParams = isp;
    }

    @Override
    public IWorldManager newWorldManager() {
        return new WorldManager(simulParams, newLawn());
    }

    @Override
    public IDriver newDriver() {
        return new Driver();
    }

    @Override
    public ILawn newLawn() {
        return new Lawn(simulParams);
    }

    @Override
    public IKuti newKuti(Point2D pd, double angle, IDriver driver) {
        angle = checkAngle(angle);
        return new Kuti(ECutterState.OFF, pd, angle, driver, new Radar(simulParams), simulParams.getKInitialEnergy(), simulParams);
    }

    @Override
    public IObstacle newObstacle(Line2D line2d) {
        return new Obstacle(line2d);

    }

    @Override
    public IMagneticObstacle newMagneticObstacle(IObstacle io) {
        MagneticObstacle magneticObstacle = new MagneticObstacle(io.segment());
        return magneticObstacle;
    }

    @Override
    public IChargingStation newChargingStation(Point2D center, double height, double width, double tau) {
        return new ChargingStation(center, height, width, tau);
    }

    /**
     * This method check if the angle is between -pi and +pi if it's not we
     * change is value according to our internal specification (0 to 2*pi).
     *
     * @param value
     * @return
     */
    private double checkAngle(double value) {
        // modulo of 2PI
        value = value % (2 * Math.PI);
        // add or remove 2PI depending on value.
        if (value < 0) {
            value = value + (2 * Math.PI);
        }
        return value;
    }
}
